package com.suncky.frame.utils;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

public class NotificationUtil {

    /**
     * 创建通知
     * @param context           上下文
     * @param channel           通知渠道
     * @param title             标题
     * @param text              正文文本
     * @param intent            对点按操作做出响应意图
     * @return
     */
    public static NotificationCompat.Builder createNotificationBuilder(
            Context context,
            CharSequence title,
            CharSequence text,
            Bitmap largeIcon,
            int smallIconRes,
            Intent intent,
            Channel channel
            ) {
        // 必须先创建通知渠道，然后才能在Android 8.0及更高版本上发布任何通知
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel(context, channel);
        }

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(context, channel.channelId)
                        .setPriority(getLowVersionPriority(channel)) // 通知优先级，优先级确定通知在Android7.1和更低版本上的干扰程度。
                        .setVisibility(channel.lockScreenVisibility) // 锁定屏幕公开范围
                        .setVibrate(channel.vibrate) // 震动模式
                        .setSound(channel.sound != null ? channel.sound : Settings.System.DEFAULT_NOTIFICATION_URI)    // 声音
                        .setOnlyAlertOnce(true); // 设置通知只会在通知首次出现时打断用户（通过声音、振动或视觉提示），而之后更新则不会再打断用户。

        // 标题，此为可选内容
        if (!TextUtils.isEmpty(title)) builder.setContentTitle(title);

        // 正文文本，此为可选内容
        if (!TextUtils.isEmpty(text)) builder.setContentText(text);

        if (largeIcon != null) {
            builder.setLargeIcon(largeIcon);
        }

        if (smallIconRes != 0) {
            builder.setSmallIcon(smallIconRes);
        }

        // 设置通知的点按操作，每个通知都应该对点按操作做出响应，通常是在应用中打开对应于该通知的Activity。
        if (intent != null) {
            PendingIntent pendingIntent =
                    PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(pendingIntent)
                    .setAutoCancel(true); // 在用户点按通知后自动移除通知
            if(NotificationManager.IMPORTANCE_HIGH == channel.importance) builder.setFullScreenIntent(pendingIntent, false);
        }

        return builder;
    }

    /**
     * 获取低版本的优先级
     * 要支持搭载 Android 7.1（API 级别 25）或更低版本的设备，
     * 您还必须使用 NotificationCompat 类中的优先级常量针对每条通知调用 setPriority()。
     * @param channel
     * @return
     */
    private static int getLowVersionPriority(Channel channel) {
        switch (channel.importance) {
            case NotificationManager.IMPORTANCE_HIGH:
                return NotificationCompat.PRIORITY_HIGH;
            case NotificationManager.IMPORTANCE_LOW:
                return NotificationCompat.PRIORITY_LOW;
            case NotificationManager.IMPORTANCE_MIN:
                return NotificationCompat.PRIORITY_MIN;
            default:
                return NotificationCompat.PRIORITY_DEFAULT;
        }
    }

    /**
     * 创建通知渠道
     * <p>
     * 反复调用这段代码也是安全的，因为创建现有通知渠道不会执行任何操作。
     * 注意：创建通知渠道后，您便无法更改通知行为，此时用户拥有完全控制权。不过，您仍然可以更改渠道的名称和说明。
     * @param context 上下文
     * @param channel 通知渠道
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private static void createChannel(Context context, Channel channel) {
        NotificationChannel notificationChannel = new NotificationChannel(channel.channelId, channel.name, channel.importance);
        notificationChannel.setDescription(channel.description); // 描述
        notificationChannel.setVibrationPattern(channel.vibrate);; // 震动模式
        notificationChannel.setSound(channel.sound != null ? channel.sound : Settings.System.DEFAULT_NOTIFICATION_URI,
                notificationChannel.getAudioAttributes());   // 声音
        notificationChannel.enableVibration(channel.vibrateEnable);
        notificationChannel.enableLights(channel.lightEnable);
        notificationChannel.setLightColor(channel.lightColor);
        notificationChannel.setShowBadge(channel.showBadge);
        NotificationManager notificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(notificationChannel);
    }

    /**
     * 显示通知
     *
     *
     * 请记得保存您传递到 NotificationManagerCompat.notify() 的通知 ID，因为如果之后您想要更新或移除通知，将需要使用这个 ID。
     * @param context      上下文
     * @param id           通知的唯一ID
     * @param notification 通知
     */
    public static void notify(Context context, int id, Notification notification) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(id, notification);
    }

    /**
     * 取消通知
     * @param context 上下文
     * @param id      通知的唯一ID
     */
    public static void cancel(Context context, int id) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(id);
    }

    /**
     * 取消所有通知
     * @param context 上下文
     */
    public static void cancelAll(Context context) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();
    }

    /**
     * 应用通知是否开启
     * @param context
     */
    public static boolean isNotificationEnable(Context context) {
        return NotificationManagerCompat.from(context).areNotificationsEnabled();
    }

    /**
     * 前往应用通知系统设置界面
     * @param context
     */
    public static void notificationSetup(Context context) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= 26) {
            // android 8.0引导
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
        } else if (Build.VERSION.SDK_INT >= 21) {
            // android 5.0-7.0
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else {
            // 其他
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    /**
     * 通知渠道
     */
    public static class Channel {
        String channelId; // 唯一渠道ID
        CharSequence name;  // 用户可见名称
        int importance; // 重要性级别
        String description;   // 描述
        @NotificationCompat.NotificationVisibility
        int lockScreenVisibility;   // 锁定屏幕公开范围
        boolean vibrateEnable;  // 开启震动
        long[] vibrate;  // 震动模式
        Uri sound;  // 声音
        boolean showBadge;//桌面应用图标角标
        boolean lightEnable;//开启闪光灯
        int lightColor;//通知出现时的闪光灯

        private Channel(Builder builder) {
            channelId = builder.channelId;
            name = builder.name;
            importance = builder.importance;
            description = builder.description;
            lockScreenVisibility = builder.lockScreenVisibility;
            vibrateEnable = builder.vibrateEnable;
            vibrate = builder.vibrate;
            sound = builder.sound;
            showBadge = builder.showBadge;
            lightEnable = builder.lightEnable;
            lightColor = builder.lightColor;
        }


        public static final class Builder {
            private String channelId;
            private CharSequence name;
            private int importance;
            private String description;
            @NotificationCompat.NotificationVisibility
            private int lockScreenVisibility;
            private long[] vibrate;
            private Uri sound;
            boolean vibrateEnable = false;
            boolean showBadge = true;
            boolean lightEnable = false;
            int lightColor;

            public Builder() {
            }

            public Builder channelId(String val) {
                channelId = val;
                return this;
            }

            public Builder name(CharSequence val) {
                name = val;
                return this;
            }

            public Builder importance(int val) {
                importance = val;
                return this;
            }

            public Builder description(String val) {
                description = val;
                return this;
            }

            public Builder lockScreenVisibility(@NotificationCompat.NotificationVisibility int val) {
                lockScreenVisibility = val;
                return this;
            }

            public Builder vibrateEnable(boolean val) {
                vibrateEnable = val;
                return this;
            }

            public Builder vibrate(long[] val) {
                vibrate = val;
                return this;
            }

            public Builder sound(Uri val) {
                sound = val;
                return this;
            }

            public Builder showBadge(boolean val) {
                showBadge = val;
                return this;
            }

            public Builder lightEnable(boolean val) {
                lightEnable = val;
                return this;
            }

            public Builder lightColor(int val) {
                lightColor = val;
                return this;
            }

            public Channel build() {
                return new Channel(this);
            }
        }
    }

}
